package com.zhzh.sc.demo.juc.interview;

//import com.zhzh.sc.demo.juc.interview.IA;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface IA {
    String getHelloName();
}

public class CreateObject {
    public static void main(String[] arges) throws Exception {
        IA ia = (IA) createObject2(IA.class.getName() + "$getHelloName=Abc");
        System.out.println(ia.getHelloName()); //方法名匹配的时候，输出“Abc”
        ia = (IA) createObject(IA.class.getName() + "$getTest=Bcd");
        System.out.println(ia.getHelloName()); //方法名不匹配的时候，输出null
    }

    //请实现方法createObject，接口中"getName()"方法名仅仅是个示例，不能写死判断

    public static Object createObject(String str) throws Exception {
        final String className = str.substring(0, str.lastIndexOf("$"));
        final String methodName = str.substring(str.lastIndexOf("$") + 1, str.indexOf("=")).trim();
        final String value = str.substring(str.indexOf("=") + 1).trim();
        return Proxy.newProxyInstance(Class.forName(className).getClassLoader(), new Class[]{Class.forName(className)},
                (proxy, method, methodArgs) -> {
                    if (method.getName().equals(methodName)) {
                        return value;
                    } else {
                        return null;
//                        throw new UnsupportedOperationException("Unsupported method: " + method.getName());
                    }
                });
    }

    public static Object createObject2(String str) throws Exception {
        String[] strTemp = str.split("\\$");

        String className = strTemp[0];

        String[] mStrTemp = strTemp[1].split("=");
        String methodName = mStrTemp[0];
        String value = mStrTemp[1];
        System.out.println(methodName + " " + value);

        Class clazz = Class.forName(className);

        return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new MyInvocationHandle(methodName, value));
    }

    static class MyInvocationHandle implements InvocationHandler {

        private String methodName;
        private String value;

        public MyInvocationHandle(String methodName, String value) {
            this.methodName = methodName;
            this.value = value;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (methodName.equals(method.getName())) {
                return value;
            }
            return null;
        }
    }

}

